package com.hixtrip.sample.app.service;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hixtrip.sample.app.api.OrderService;
import com.hixtrip.sample.app.api.PayResultService;
import com.hixtrip.sample.client.constant.DelFlagEnum;
import com.hixtrip.sample.client.constant.PayStatus;
import com.hixtrip.sample.client.exception.ServiceException;
import com.hixtrip.sample.client.order.dto.CommandOderCreateDTO;
import com.hixtrip.sample.client.order.dto.CommandPayDTO;
import com.hixtrip.sample.client.sample.vo.OrderVO;
import com.hixtrip.sample.client.sample.vo.PayCallbackVO;
import com.hixtrip.sample.domain.commodity.CommodityDomainService;
import com.hixtrip.sample.domain.inventory.InventoryDomainService;
import com.hixtrip.sample.domain.order.OrderDomainService;
import com.hixtrip.sample.domain.order.model.Order;
import com.hixtrip.sample.domain.pay.PayDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

/**
 * app层负责处理request请求，调用领域服务
 */
@Component
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDomainService orderDomainService;

    @Autowired
    private CommodityDomainService commodityDomainService;

    @Autowired
    private InventoryDomainService inventoryDomainService;

    @Autowired
    private PayDomainService payDomainService;

    @Autowired
    private Map<String, PayResultService> payResultServiceMap;

    /**
     * 创建订单
     */
    @Override
    public OrderVO order(CommandOderCreateDTO commandOderCreateDTO) {

        // 基本信息校验
        if (StringUtils.isBlank(commandOderCreateDTO.getUserId())){
            throw new ServiceException("请先登录后进行操作!");
        }
        if (StringUtils.isBlank(commandOderCreateDTO.getSkuId())){
            throw new ServiceException("skuId不能为空!");
        }
        if (commandOderCreateDTO.getAmount() == null || Objects.equals(commandOderCreateDTO.getAmount(), 0)){
            throw new ServiceException("订单数量不能为空!");
        }

        BigDecimal skuPrice = commodityDomainService.getSkuPrice(commandOderCreateDTO.getSkuId());
        if (skuPrice == null){
            throw new ServiceException("商品不存在!");
        }
        BigDecimal money = skuPrice.multiply(new BigDecimal(commandOderCreateDTO.getAmount()));

        // 校验库存
        Integer inventory = inventoryDomainService.getInventory(commandOderCreateDTO.getSkuId());
        if (inventory < commandOderCreateDTO.getAmount()){
            throw new ServiceException("商品库存不足!");
        }

        Order order = new Order();
        order.setUserId(commandOderCreateDTO.getUserId());
        order.setSkuId(commandOderCreateDTO.getSkuId());
        order.setAmount(commandOderCreateDTO.getAmount());
        order.setMoney(money);
        order.setPayTime(LocalDateTime.now());
        order.setPayStatus(PayStatus.PAY_WAIT_STATUS);
        order.setDelFlag(DelFlagEnum.NORMAL.getCode());
        order.setCreateBy(commandOderCreateDTO.getUserId());
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateBy(commandOderCreateDTO.getUserId());
        order.setUpdateTime(LocalDateTime.now());

        // 创建待付款订单
        orderDomainService.createOrder(order);

        // 扣减库存
        Boolean isSuccess = inventoryDomainService.changeInventory(order.getSkuId(), inventory.longValue(), commandOderCreateDTO.getAmount().longValue(), null);
        if (!isSuccess){
            throw new ServiceException("商品过于火爆,请稍候重试!");
        }

        // 发起支付(模拟)
        payDomainService.pay();

        return OrderVO.builder()
                .id(order.getId())
                .code("200")
                .msg("订单创建成功!")
                .build();
    }

    /**
     * 支付回调
     */
    @Override
    public PayCallbackVO payCallback(CommandPayDTO commandPayDTO) {
        PayResultService payResultService = payResultServiceMap.get(PayResultService.BEAN_NAME_PREFIX + commandPayDTO.getPayStatus());
        if (payResultService == null){
            throw new ServiceException("提供的支付状态不存在!");
        }
        return payResultService.dealPayResult(commandPayDTO);
    }
}
